<script setup lang="ts">
import { ref, computed, nextTick, watch, onMounted } from "vue";
import type { Message as ChatMessage } from "@/api/customer-service";
import { dayjs } from "element-plus";

interface Props {
  messages?: ChatMessage[];
  loading?: boolean;
  hasMore?: boolean;
}

interface Emits {
  (e: "loadMore"): void;
  (e: "imagePreview", url: string): void;
}

const props = withDefaults(defineProps<Props>(), {
  messages: () => [],
  loading: false,
  hasMore: false
});

const emit = defineEmits<Emits>();

const messageListRef = ref<HTMLElement>();
const isAtBottom = ref(true);

// Format time display 格式化时间显示 - 聊天记录专用
const formatMessageTime = (timestamp: string) => {
  const now = dayjs();
  const messageTime = dayjs(timestamp);

  // 处理未来时间（时间不一致时）- 当作当天处理
  if (messageTime.isAfter(now)) {
    return messageTime.format("HH:mm");
  }

  const diffDays = now.diff(messageTime, "day");

  // 当天消息：显示 HH:mm
  if (diffDays === 0) {
    return messageTime.format("HH:mm");
  }

  // 昨天消息：显示 昨天 HH:mm
  if (diffDays === 1) {
    return `昨天 ${messageTime.format("HH:mm")}`;
  }

  // 前天消息：显示 前天 HH:mm
  if (diffDays === 2) {
    return `前天 ${messageTime.format("HH:mm")}`;
  }

  // 一周内消息：显示 星期X HH:mm
  if (diffDays < 7) {
    const weekdays = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
    const weekday = weekdays[messageTime.day()];
    return `${weekday} ${messageTime.format("HH:mm")}`;
  }

  // 本年其他时间：显示 MM-DD HH:mm
  if (now.isSame(messageTime, "year")) {
    return messageTime.format("MM-DD HH:mm");
  }

  // 跨年消息：显示 YYYY-MM-DD HH:mm
  return messageTime.format("YYYY-MM-DD HH:mm");
};

// 检查消息是否来自当前用户 (客服/管理员)
const isOwnMessage = (message: ChatMessage) => {
  // 优先使用 is_own 字段，如果没有则检查 sender_type 是否为 AdminUser
  if (message.is_own !== undefined) {
    return message.is_own;
  }
  // 判断是否为客服（管理员）发送的消息
  return message.sender?.type === "AdminUser";
};

// 检查与上一条消息，是否应该显示时间分隔符
// 规则：第一条消息总是显示，或者与上一条消息间隔超过5分钟
const shouldShowTime = (message: ChatMessage, index: number) => {
  // 第一条消息总是显示时间
  if (index === 0) return true;

  const prevMessage = props.messages[index - 1];
  const currentTime = dayjs(message.created_at);
  const prevTime = dayjs(prevMessage.created_at);

  // 计算时间差（分钟）- 使用绝对值处理时间不一致
  const timeDiff = Math.abs(currentTime.diff(prevTime, "minute"));

  // 如果跨天了，一定显示时间
  if (!currentTime.isSame(prevTime, "day")) {
    return true;
  }

  // 同一天内，如果间隔超过5分钟则显示时间
  return timeDiff > 1;
};

// Get file name from URL
const getFileName = (url: string) => {
  try {
    const urlObj = new URL(url);
    const pathParts = urlObj.pathname.split("/");
    return pathParts[pathParts.length - 1] || "file";
  } catch {
    return "file";
  }
};

// Scroll to bottom
const scrollToBottom = (smooth = true) => {
  nextTick(() => {
    if (messageListRef.value) {
      messageListRef.value.scrollTo({
        top: messageListRef.value.scrollHeight,
        behavior: smooth ? "smooth" : "auto"
      });
    }
  });
};

// Handle scroll event
const handleScroll = () => {
  if (!messageListRef.value) return;

  const { scrollTop, scrollHeight, clientHeight } = messageListRef.value;
  isAtBottom.value = scrollHeight - scrollTop - clientHeight < 100;

  // Load more when scrolled to top
  if (scrollTop < 100 && props.hasMore && !props.loading) {
    emit("loadMore");
  }
};

// Handle image click
const handleImageClick = (url: string) => {
  emit("imagePreview", url);
};

// Watch messages and auto scroll
watch(
  () => props.messages.length,
  () => {
    if (isAtBottom.value) {
      scrollToBottom();
    }
  }
);

onMounted(() => {
  scrollToBottom(false);
});

defineExpose({
  scrollToBottom
});
</script>

<template>
  <div class="message-stream">
    <div ref="messageListRef" class="message-list" @scroll="handleScroll">
      <!-- Loading indicator -->
      <div v-if="loading" class="loading-indicator">
        <el-icon class="is-loading"><Loading /></el-icon>
        <span>加载消息中...</span>
      </div>

      <!-- Messages 消息记录-->
      <div v-for="(message, index) in messages" :key="message.id" class="message-wrapper">
        <!-- Time divider -->
        <div v-if="shouldShowTime(message, index)" class="time-divider">
          <span>{{ formatMessageTime(message.created_at) }}</span>
        </div>

        <!-- Message item 消息项 -->
        <div class="message-item" :class="{ 'own-message': isOwnMessage(message) }">
          <!-- Avatar (左边给别人) -->
          <el-avatar
            v-if="!isOwnMessage(message)"
            :src="message?.sender?.avatar || ''"
            :size="36"
            class="message-avatar"
          >
            {{ message?.sender?.name.charAt(0) || "" }}
          </el-avatar>

          <!-- Message content -->
          <div class="message-content">
            <!-- 发件人姓名（用于群聊) -->
            <div v-if="!isOwnMessage(message)" class="sender-name">
              {{ message?.sender?.name || "" }}
            </div>

            <!-- Message bubble 消息气泡 -->
            <div class="message-bubble" :class="`type-${message.message_type}`">
              <!-- Text message -->
              <div v-if="message.message_type === 'text'" class="text-content">
                {{ message.content }}
              </div>

              <!-- Image message -->
              <el-image
                v-else-if="message.message_type === 'image'"
                :src="message.content"
                fit="cover"
                class="image-content"
                :preview-src-list="[message.content]"
                @click="handleImageClick(message.content)"
              />

              <!-- File message -->
              <div v-else-if="message.message_type === 'file'" class="file-content">
                <el-icon class="file-icon"><Document /></el-icon>
                <div class="file-info">
                  <div class="file-name">
                    {{ getFileName(message.content) }}
                  </div>
                  <el-link :href="message.content" target="_blank" type="primary"> Download </el-link>
                </div>
              </div>

              <!-- System message -->
              <div v-else-if="message.message_type === 'system'" class="system-content">
                {{ message.content }}
              </div>
            </div>

            <!-- Message time -->
            <div class="message-time">
              {{ dayjs(message.created_at).format("HH:mm") }}
            </div>
          </div>

          <!-- Avatar (右侧为自己的消息) -->
          <el-avatar
            v-if="isOwnMessage(message)"
            :src="message?.sender?.avatar || ''"
            :size="36"
            class="message-avatar"
          >
            {{ message?.sender?.name.charAt(0) }}
          </el-avatar>
        </div>
      </div>

      <!-- Empty state 空状态 -->
      <el-empty v-if="messages.length === 0 && !loading" description="暂无消息" :image-size="120" />
    </div>

    <!-- Scroll to bottom button -->
    <transition name="fade">
      <el-button v-if="!isAtBottom" circle class="scroll-to-bottom" @click="scrollToBottom()">
        <el-icon><ArrowDown /></el-icon>
      </el-button>
    </transition>
  </div>
</template>

<style lang="scss" scoped>
.message-stream {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 420px;
}

.message-list {
  flex: 1;
  padding: 16px;
  overflow-y: auto;
  background: #f5f7fa;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-thumb {
    background: #dcdfe6;
    border-radius: 3px;

    &:hover {
      background: #c0c4cc;
    }
  }
}

.loading-indicator {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: center;
  padding: 12px;
  font-size: 14px;
  color: #909399;
}

.time-divider {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 16px 0;

  span {
    padding: 4px 12px;
    font-size: 12px;
    color: #909399;
    background: #e4e7ed;
    border-radius: 12px;
  }
}

.message-wrapper {
  margin-bottom: 16px;
}

.message-item {
  display: flex;
  gap: 12px;
  animation: slideIn 0.3s ease;

  &.own-message {
    display: flex;
    flex-direction: row;
    justify-content: flex-end;

    .message-content {
      align-items: flex-end;
    }

    .message-bubble {
      color: #fff;
      background: #59bdc6;
    }

    .message-time {
      text-align: right;
    }
  }
}

.message-avatar {
  flex-shrink: 0;
}

.message-content {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-width: 60%;
}

.sender-name {
  padding: 0 8px;
  font-size: 12px;
  color: #909399;
}

.message-bubble {
  padding: 10px 14px;
  word-break: break-word;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 1px 2px rgb(0 0 0 / 5%);

  &.type-system {
    font-size: 12px;
    color: #909399;
    text-align: center;
    background: #f4f4f5;
  }
}

.text-content {
  line-height: 1.6;
  white-space: pre-wrap;
}

.image-content {
  max-width: 200px;
  max-height: 200px;
  cursor: pointer;
  border-radius: 4px;
}

.file-content {
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 8px;

  .file-icon {
    font-size: 32px;
    color: #409eff;
  }

  .file-info {
    flex: 1;
  }

  .file-name {
    margin-bottom: 4px;
    font-size: 14px;
    color: #303133;
  }
}

.system-content {
  font-size: 12px;
  text-align: center;
}

.message-time {
  padding: 0 8px;
  font-size: 11px;
  color: #c0c4cc;
}

.scroll-to-bottom {
  position: absolute;
  right: 20px;
  bottom: 20px;
  z-index: 10;
  box-shadow: 0 2px 8px rgb(0 0 0 / 15%);
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
